home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / ViePratique / ArchiFacile / ArchiFacileSetup.exe / {app} / nw.pak / Unnamed File 000134.txt < prev    next >
Text File  |  2014-10-14  |  8KB  |  244 lines

  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4.  
  5. /**
  6.  * @fileoverview This file provides utility functions for position popups.
  7.  */
  8.  
  9. cr.define('cr.ui', function() {
  10.  
  11.   /**
  12.    * Type def for rects as returned by getBoundingClientRect.
  13.    * @typedef { {left: number, top: number, width: number, height: number,
  14.    *             right: number, bottom: number}}
  15.    */
  16.   var Rect;
  17.  
  18.   /**
  19.    * Enum for defining how to anchor a popup to an anchor element.
  20.    * @enum {number}
  21.    */
  22.   var AnchorType = {
  23.     /**
  24.      * The popup's right edge is aligned with the left edge of the anchor.
  25.      * The popup's top edge is aligned with the top edge of the anchor.
  26.      */
  27.     BEFORE: 1,  // p: right, a: left, p: top, a: top
  28.  
  29.     /**
  30.      * The popop's left edge is aligned with the right edge of the anchor.
  31.      * The popup's top edge is aligned with the top edge of the anchor.
  32.      */
  33.     AFTER: 2,  // p: left a: right, p: top, a: top
  34.  
  35.     /**
  36.      * The popop's bottom edge is aligned with the top edge of the anchor.
  37.      * The popup's left edge is aligned with the left edge of the anchor.
  38.      */
  39.     ABOVE: 3,  // p: bottom, a: top, p: left, a: left
  40.  
  41.     /**
  42.      * The popop's top edge is aligned with the bottom edge of the anchor.
  43.      * The popup's left edge is aligned with the left edge of the anchor.
  44.      */
  45.     BELOW: 4  // p: top, a: bottom, p: left, a: left
  46.   };
  47.  
  48.   /**
  49.    * Helper function for positionPopupAroundElement and positionPopupAroundRect.
  50.    * @param {!Rect} anchorRect The rect for the anchor.
  51.    * @param {!HTMLElement} popupElement The element used for the popup.
  52.    * @param {AnchorType} type The type of anchoring to do.
  53.    * @param {boolean} invertLeftRight Whether to invert the right/left
  54.    *     alignment.
  55.    */
  56.   function positionPopupAroundRect(anchorRect, popupElement, type,
  57.                                    invertLeftRight) {
  58.     var popupRect = popupElement.getBoundingClientRect();
  59.     var availRect;
  60.     var ownerDoc = popupElement.ownerDocument;
  61.     var cs = ownerDoc.defaultView.getComputedStyle(popupElement);
  62.     var docElement = ownerDoc.documentElement;
  63.  
  64.     if (cs.position == 'fixed') {
  65.       // For 'fixed' positioned popups, the available rectangle should be based
  66.       // on the viewport rather than the document.
  67.       availRect = {
  68.         height: docElement.clientHeight,
  69.         width: docElement.clientWidth,
  70.         top: 0,
  71.         bottom: docElement.clientHeight,
  72.         left: 0,
  73.         right: docElement.clientWidth
  74.       };
  75.     } else {
  76.       availRect = popupElement.offsetParent.getBoundingClientRect();
  77.     }
  78.  
  79.     if (cs.direction == 'rtl')
  80.       invertLeftRight = !invertLeftRight;
  81.  
  82.     // Flip BEFORE, AFTER based on alignment.
  83.     if (invertLeftRight) {
  84.       if (type == AnchorType.BEFORE)
  85.         type = AnchorType.AFTER;
  86.       else if (type == AnchorType.AFTER)
  87.         type = AnchorType.BEFORE;
  88.     }
  89.  
  90.     // Flip type based on available size
  91.     switch (type) {
  92.       case AnchorType.BELOW:
  93.         if (anchorRect.bottom + popupRect.height > availRect.height &&
  94.             popupRect.height <= anchorRect.top) {
  95.           type = AnchorType.ABOVE;
  96.         }
  97.         break;
  98.       case AnchorType.ABOVE:
  99.         if (popupRect.height > anchorRect.top &&
  100.             anchorRect.bottom + popupRect.height <= availRect.height) {
  101.           type = AnchorType.BELOW;
  102.         }
  103.         break;
  104.       case AnchorType.AFTER:
  105.         if (anchorRect.right + popupRect.width > availRect.width &&
  106.             popupRect.width <= anchorRect.left) {
  107.           type = AnchorType.BEFORE;
  108.         }
  109.         break;
  110.       case AnchorType.BEFORE:
  111.         if (popupRect.width > anchorRect.left &&
  112.             anchorRect.right + popupRect.width <= availRect.width) {
  113.           type = AnchorType.AFTER;
  114.         }
  115.         break;
  116.     }
  117.     // flipping done
  118.  
  119.     var style = popupElement.style;
  120.     // Reset all directions.
  121.     style.left = style.right = style.top = style.bottom = 'auto';
  122.  
  123.     // Primary direction
  124.     switch (type) {
  125.       case AnchorType.BELOW:
  126.         if (anchorRect.bottom + popupRect.height <= availRect.height)
  127.           style.top = anchorRect.bottom + 'px';
  128.         else
  129.           style.bottom = '0';
  130.         break;
  131.       case AnchorType.ABOVE:
  132.         if (availRect.height - anchorRect.top >= 0)
  133.           style.bottom = availRect.height - anchorRect.top + 'px';
  134.         else
  135.           style.top = '0';
  136.         break;
  137.       case AnchorType.AFTER:
  138.         if (anchorRect.right + popupRect.width <= availRect.width)
  139.           style.left = anchorRect.right + 'px';
  140.         else
  141.           style.right = '0';
  142.         break;
  143.       case AnchorType.BEFORE:
  144.         if (availRect.width - anchorRect.left >= 0)
  145.           style.right = availRect.width - anchorRect.left + 'px';
  146.         else
  147.           style.left = '0';
  148.         break;
  149.     }
  150.  
  151.     // Secondary direction
  152.     switch (type) {
  153.       case AnchorType.BELOW:
  154.       case AnchorType.ABOVE:
  155.         if (invertLeftRight) {
  156.           // align right edges
  157.           if (anchorRect.right - popupRect.width >= 0) {
  158.             style.right = availRect.width - anchorRect.right + 'px';
  159.  
  160.           // align left edges
  161.           } else if (anchorRect.left + popupRect.width <= availRect.width) {
  162.             style.left = anchorRect.left + 'px';
  163.  
  164.           // not enough room on either side
  165.           } else {
  166.             style.right = '0';
  167.           }
  168.         } else {
  169.           // align left edges
  170.           if (anchorRect.left + popupRect.width <= availRect.width) {
  171.             style.left = anchorRect.left + 'px';
  172.  
  173.           // align right edges
  174.           } else if (anchorRect.right - popupRect.width >= 0) {
  175.             style.right = availRect.width - anchorRect.right + 'px';
  176.  
  177.           // not enough room on either side
  178.           } else {
  179.             style.left = '0';
  180.           }
  181.         }
  182.         break;
  183.  
  184.       case AnchorType.AFTER:
  185.       case AnchorType.BEFORE:
  186.         // align top edges
  187.         if (anchorRect.top + popupRect.height <= availRect.height) {
  188.           style.top = anchorRect.top + 'px';
  189.  
  190.         // align bottom edges
  191.         } else if (anchorRect.bottom - popupRect.height >= 0) {
  192.           style.bottom = availRect.height - anchorRect.bottom + 'px';
  193.  
  194.           // not enough room on either side
  195.         } else {
  196.           style.top = '0';
  197.         }
  198.         break;
  199.     }
  200.   }
  201.  
  202.   /**
  203.    * Positions a popup element relative to an anchor element. The popup element
  204.    * should have position set to absolute and it should be a child of the body
  205.    * element.
  206.    * @param {!HTMLElement} anchorElement The element that the popup is anchored
  207.    *     to.
  208.    * @param {!HTMLElement} popupElement The popup element we are positioning.
  209.    * @param {AnchorType} type The type of anchoring we want.
  210.    * @param {boolean} invertLeftRight Whether to invert the right/left
  211.    *     alignment.
  212.    */
  213.   function positionPopupAroundElement(anchorElement, popupElement, type,
  214.                                       invertLeftRight) {
  215.     var anchorRect = anchorElement.getBoundingClientRect();
  216.     positionPopupAroundRect(anchorRect, popupElement, type, invertLeftRight);
  217.   }
  218.  
  219.   /**
  220.    * Positions a popup around a point.
  221.    * @param {number} x The client x position.
  222.    * @param {number} y The client y position.
  223.    * @param {!HTMLElement} popupElement The popup element we are positioning.
  224.    */
  225.   function positionPopupAtPoint(x, y, popupElement) {
  226.     var rect = {
  227.       left: x,
  228.       top: y,
  229.       width: 0,
  230.       height: 0,
  231.       right: x,
  232.       bottom: y
  233.     };
  234.     positionPopupAroundRect(rect, popupElement, AnchorType.BELOW);
  235.   }
  236.  
  237.   // Export
  238.   return {
  239.     AnchorType: AnchorType,
  240.     positionPopupAroundElement: positionPopupAroundElement,
  241.     positionPopupAtPoint: positionPopupAtPoint
  242.   };
  243. });
  244.